home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume20 / notation / part04 < prev    next >
Encoding:
Text File  |  1991-06-18  |  43.8 KB  |  1,860 lines

  1. Newsgroups: comp.sources.misc
  2. From: Henry Thomas <hthomas@irisa.fr>
  3. Subject:  v20i055:  notation - chess text handler, Part04/04
  4. Message-ID: <1991Jun17.051704.2793@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 6d45e78820426a7440322c07db224a7f
  6. Date: Mon, 17 Jun 1991 05:17:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Henry Thomas <hthomas@irisa.fr>
  10. Posting-number: Volume 20, Issue 55
  11. Archive-name: notation/part04
  12. Supersedes: notation: Volume 18, Issue 12-14
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 4 (of 4)."
  21. # Contents:  notation.c
  22. # Wrapped by hthomas@cattus on Sun Jun 16 18:17:28 1991
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'notation.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'notation.c'\"
  26. else
  27. echo shar: Extracting \"'notation.c'\" \(40751 characters\)
  28. sed "s/^X//" >'notation.c' <<'END_OF_FILE'
  29. X/*
  30. X  Notation program
  31. X  @(#)notation.c    3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91
  32. X */
  33. X/* Programme d'analyse de notation echiquienne
  34. X   Copyright (C) 1990 Henry Thomas
  35. X   Nom: notation
  36. X   Auteur: Henry Thomas
  37. X   Date: 27/11/90
  38. X/*
  39. XThis file is part of NOTATION program.
  40. X
  41. XNOTATION is free software; you can redistribute it and/or modify
  42. Xit under the terms of the GNU General Public License as published by
  43. Xthe Free Software Foundation; either version 1, or (at your option)
  44. Xany later version.
  45. X
  46. XNOTATION is distributed in the hope that it will be useful,
  47. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  48. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  49. XGNU General Public License for more details.
  50. X
  51. XYou should have received a copy of the GNU General Public License
  52. Xalong with NOTATION; see the file COPYING.  If not, write to
  53. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  54. X
  55. X/* --------------------- data part ---------------------- */
  56. X
  57. X/* les tableaux suivants sont les tables de transcription de notation
  58. X   selon les langages
  59. X   */
  60. X#ifdef __STDC__
  61. X#include <stdlib.h>
  62. X#endif
  63. X#include <stdio.h>
  64. X#include <string.h>
  65. X#include <ctype.h>
  66. X
  67. X#include "chesstype.h"
  68. X#include "notation.h"
  69. X#include "drivers.h"
  70. X#include "lexer.h"
  71. X
  72. Xextern void close_files();
  73. X
  74. Xchar * version_string =
  75. X  "@(#)notation.c    3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91";
  76. X
  77. Xstatic char * keywords[]= {
  78. X  "@startplay" , "@clearboard" , "@showboard" ,
  79. X  "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
  80. X  "@default" , 
  81. X  /* these are keywords with arguments */
  82. X  "@title", "@subtitle", "@score", "@language",
  83. X  /* "special" keyword */
  84. X  "@special", 
  85. X  /* null and final keyword */
  86. X  "@null"
  87. X  };
  88. X
  89. Xint configuring = FALSE ;
  90. Xint configside = 0 ;
  91. X
  92. X
  93. Xstatic char * t_language[] = {
  94. X  "french", "english", "italian", "spanish", "german", "dutch",
  95. X  "czech",  "hungarian","polish", "romanian", "FIDE"
  96. X};
  97. X
  98. Xstatic int in_language = DEFAULT_INPUT_LANGUAGE ;
  99. Xstatic int out_language = DEFAULT_OUTPUT_LANGUAGE ;
  100. X
  101. Xstatic char c_language[NBLANGUAGES][7] = {
  102. X/* french    */  { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' },
  103. X/* english   */  { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' },
  104. X/* italian   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
  105. X/* spanish   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
  106. X/* german    */  { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' },
  107. X/* dutch     */  { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' },
  108. X/* czech     */  { '@' ,'K' , 'D' , 'V' , 'S' , 'J' , 'P' },
  109. X/* hungarian */  { '@' ,'K' , 'V' , 'B' , 'F' , 'H' , 'G' },
  110. X/* polish    */  { '@' ,'K' , 'H' , 'W' , 'G' , 'S' , 'P' },
  111. X/* romanian  */  { '@' ,'R' , 'D' , 'T' , 'N' , 'C' , 'P' },
  112. X/* FIDE      */  { '@' ,'K' , 'D' , 'T' , 'S' , 'N' , 'P' }
  113. X/* UNIMPLEMENTED ... */
  114. X/* user_def  *//*{ '@' ,'X' , 'X' , 'X' , 'X' , 'X' , 'X' }*/
  115. X/* russian not implemented : ASCII russian is an oxymoron */
  116. X/* russian   *//*{ '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' }*/
  117. X           };
  118. X
  119. X/* input translation table */
  120. Xchar *in_table;
  121. X
  122. Xchar *  c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
  123. X
  124. X/* various notations for en passant */
  125. X#define N_EP 2
  126. Xchar * c_en_passant[] = { "ep" , "e.p." } ;
  127. X
  128. X
  129. X/* notation for catch */
  130. Xchar c_prise ='x';
  131. X
  132. X/* various comments */
  133. Xchar * c_comments[] = { "+" , "++" , 
  134. X              "?" , "??", "!", "!!", "!?", "?!",
  135. X              "mate", "draw" };
  136. X
  137. X/* movement tables */
  138. X/* move only */
  139. X/* white pawn, move */
  140. X#define NB_M_PAWN_MOVE_WD 2
  141. Xstatic int m_pawn_move_wd [][2] = {
  142. X  { 1, 0}, {2, 0}
  143. X};
  144. X
  145. X/* black pawn, move */
  146. X#define NB_M_PAWN_MOVE_BD 2
  147. Xstatic int m_pawn_move_bd [][2] = {
  148. X  {-1, 0}, {-2, 0}
  149. X};
  150. X
  151. X/* TRICK = we have added the catching move at the end of
  152. X   the non catching ones; so in check_depl, we try first 
  153. X   the non catching one and then the catching one.
  154. X   So, even if catching (x) is non indicated in the input, 
  155. X   we succeed in guessing the move
  156. X   */
  157. X/* white pawn, move */
  158. X/*#define NB_M_PAWN_WD 2*/
  159. X#define NB_M_PAWN_WD 4
  160. Xstatic int m_pawn_wd [][2] = {
  161. X  { 1, 0}, {2, 0},
  162. X/* catch... */
  163. X  { 1, 1}, { 1,-1}
  164. X};
  165. X
  166. X/* white pawn, catch */
  167. X#define NB_M_PAWN_WX 2
  168. Xstatic int m_pawn_wx [][2] = {
  169. X  { 1, 1}, { 1,-1}
  170. X};
  171. X
  172. X/* black pawn, move */
  173. X/*#define NB_M_PAWN_BD 2*/
  174. X#define NB_M_PAWN_BD 4
  175. Xstatic int m_pawn_bd [][2] = {
  176. X  {-1, 0}, {-2, 0},
  177. X/* catch... */
  178. X  {-1, 1}, {-1,-1} 
  179. X};
  180. X
  181. X/* black pawn, catch */
  182. X#define NB_M_PAWN_BX 2
  183. Xstatic int m_pawn_bx [][2] = {
  184. X  {-1, 1}, {-1,-1} 
  185. X};
  186. X
  187. X
  188. X#define NB_M_KNIGHT  8
  189. Xstatic int m_knight[][2] = { 
  190. X  { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
  191. X  { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
  192. X};
  193. X
  194. X#define NB_M_BISHOP 28
  195. Xstatic int m_bishop[][2] = {
  196. X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  197. X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  198. X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  199. X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
  200. X};
  201. X
  202. X#define NB_M_ROOK 28
  203. Xstatic int m_rook[][2] = {
  204. X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  205. X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  206. X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  207. X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  208. X};
  209. X
  210. X#define NB_M_QUEEN 56
  211. Xstatic int m_queen[][2] = {
  212. X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  213. X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  214. X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  215. X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
  216. X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  217. X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  218. X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  219. X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  220. X};
  221. X
  222. X#define NB_M_KING 8
  223. Xstatic int m_king[][2] = {
  224. X  { 1, 1}, { 1, 0}, { 1,-1},
  225. X  {-1, 1}, {-1, 0}, {-1,-1},
  226. X  { 0, 1}, { 0, -1}
  227. X};
  228. X
  229. X
  230. X/* I/O */
  231. XFILE * infile ;
  232. XFILE * fhelp;
  233. X
  234. Xstatic char * t_output[] = 
  235. X{ "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
  236. X
  237. X/* stack -- used for variation */
  238. X
  239. X/* stack element */
  240. Xtypedef struct {
  241. X  depl * d;
  242. X  game * b;
  243. X  
  244. X  /* we don't stack drivers, but only to variables */
  245. X  int d1,d2; /* iswhiteturn and interrupt */
  246. X} stack_elt ;
  247. X
  248. X/* size of the stack
  249. X   0 = ordinary play
  250. X   1 = level 1 variation
  251. X   2 = level 2 variation
  252. X   3 = level 3 variation
  253. X*/
  254. X#define VARIATION_MAX 3
  255. X
  256. X/* the stack itself */
  257. Xstatic stack_elt stack[VARIATION_MAX];
  258. X
  259. X/* top of the stack */
  260. X/* --> explicit in dr->variation */
  261. X
  262. X
  263. X/* ---------- automata definitions --------- */
  264. X/* table for syntaxic analysis of move */
  265. X
  266. X#define FINAL    10
  267. X#define TML     FINAL   /* terminal state */
  268. X#define NBETAT     11
  269. X#define NBCLAS     8
  270. X
  271. X/* successor of state */
  272. Xstatic int transit[NBETAT][NBCLAS] = { 
  273. X/*   P a-h 1-8   -   x   =  \0   ? */ 
  274. X/*(  0   1   2   3   4   5   6   7)*/
  275. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  276. X  { -1,  2, -1, -1,  4, -1, -1, -1 }, /* etat  1 */
  277. X  { -1,  6,  3,  4,  4,  8,TML,TML }, /* etat  2 */
  278. X  { -1,  6, -1,  4,  4,  8,TML,TML }, /* etat  3 */
  279. X  {  5,  6, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  280. X  { -1,  6, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  281. X  { -1, -1,  7, -1, -1, -1, -1, -1 }, /* etat  6 */
  282. X  { -1, -1, -1, -1, -1,  8,TML,TML }, /* etat  7 */
  283. X  {  9, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  284. X  { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat  9 */
  285. X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 == terminal */
  286. X};
  287. X
  288. X/* actions to do */
  289. Xstatic int action[NBETAT][NBCLAS] = {
  290. X/*   P a-h 1-8   -   x   =  \0   ? */ 
  291. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  292. X  { -1,  2, -1, -1, 10, -1, -1, -1 }, /* etat  1 */
  293. X  { -1, 13,  3,  4,  5, 14,  6,  7 }, /* etat  2 */
  294. X  { -1, 13, -1,  4,  5, 14,  6,  7 }, /* etat  3 */
  295. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  296. X  { -1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  297. X  { -1, -1,  3, -1, -1, -1, -1, -1 }, /* etat  6 */
  298. X  { -1, -1, -1, -1, -1, 14,  8,  9 }, /* etat  7 */
  299. X  { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  300. X  { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat  9 */
  301. X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 */
  302. X};
  303. X
  304. X
  305. X/* the complete play */
  306. Xplay * theplay ;
  307. X
  308. X/* current game
  309. X   the name "tos" means "top of stack"
  310. X   */
  311. Xstatic game * tos = GULL ;
  312. X
  313. X/* variable holding current move */
  314. Xstatic depl * m = MULL ;
  315. X
  316. X/* the output driver */
  317. Xstatic format * dr;
  318. X
  319. Xstatic int driver; /* driver type, ie gnu, ascii ... */
  320. X
  321. Xstatic int movecount;
  322. X
  323. X/* current move, used by the parser */
  324. Xstatic int curpiece,  curcol,  curlig ;
  325. Xstatic int curdigit, curmove;
  326. X
  327. X/* booleen d'erreur */
  328. Xint error_flag = FALSE;
  329. X
  330. X/* move to display board */
  331. Xstatic int count = 0 ;
  332. X
  333. Xstatic int move_to_display[NB_MOVE_TO_DISP] ;
  334. Xstatic int nb_move_to_dsp = 0;
  335. Xstatic int stop_at_display = FALSE;
  336. X
  337. X/* short and long form comment table */
  338. Xchar * com_short[] = {
  339. X#define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) SASC,
  340. X#include "chesssymb.def"
  341. X ""
  342. X };
  343. X#undef CHESSSYMB
  344. X
  345. Xchar * com_long[] = {
  346. X#define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) LASC,
  347. X#include "chesssymb.def"
  348. X ""
  349. X };
  350. X#undef CHESSSYMB
  351. X
  352. X
  353. X
  354. X#define setboard(A,I,J,P,C)  { (A)->board[(I)][(J)] = (P) ; \
  355. X                 (A)->color[(I)][(J)] = (C); }
  356. X#define clsboard(A,I,J)   { (A)->board[(I)][(J)] = VOID ; \
  357. X                (A)->color[(I)][(J)] = VOID ;}
  358. X
  359. X/* --------------------------- code part --------------------- */
  360. X
  361. X
  362. X#ifdef __STDC__
  363. Xstatic int ispiece(char c)
  364. X#else
  365. Xstatic int ispiece(c)
  366. X     char c;
  367. X#endif
  368. X{
  369. X  register int i;
  370. X  
  371. X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  372. X  /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
  373. X  return(i<NUMPIECES);
  374. X}
  375. X
  376. X
  377. X#ifdef __STDC__
  378. Xstatic int piece(char c)
  379. X#else
  380. Xstatic int piece(c)
  381. X     char c ;
  382. X#endif
  383. X{
  384. X  register int i;
  385. X  
  386. X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  387. X  if ( i== NUMPIECES)
  388. X    i = PAWN ;
  389. X  return(i);
  390. X}
  391. X
  392. X/* this function return yhe # entry of a keyword in a given table.
  393. X   if key is not present, it returns the default value
  394. X   */
  395. X#ifdef __STDC__
  396. Xstatic int find_keyword(char *tab[], int nbentry,int defaut,
  397. X            char *key,int warning)
  398. X#else
  399. Xstatic int find_keyword(tab, nbentry,defaut,key,warning)
  400. X     char * tab[]; /* the table to look in */
  401. X     int nbentry;  /* number of entries */
  402. X     int defaut;  /* the default value to return if search failed */
  403. X     char *key;    /* the key to find */
  404. X     int warning;  /* do we display a warning ? */
  405. X#endif
  406. X{
  407. X  int i ;
  408. X
  409. X  for(i=0; (i< nbentry) ;i++)
  410. X    if (strcmp(tab[i],key)==0)
  411. X      return(i);
  412. X
  413. X  /* we failed to find the keyword */
  414. X  if (warning)
  415. X    (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
  416. X  return(defaut);
  417. X}
  418. X
  419. X/* ---------- board management function ------------- */
  420. X
  421. X#ifdef __STDC__
  422. Xvoid clear_board(game *g)
  423. X#else
  424. Xvoid clear_board(g)
  425. X     game *g;
  426. X#endif
  427. X{
  428. X  register int i,j;
  429. X
  430. X  for (i=0; i < 10; i++ )
  431. X    for (j=0 ; j< 10 ; j++) {
  432. X      g->board[i][j] = VOID;
  433. X      g->color[i][j] = VOID;
  434. X    }
  435. X}
  436. X
  437. X#ifdef __STDC__
  438. Xgame * new_board(void)
  439. X#else
  440. Xgame * new_board()
  441. X#endif
  442. X{
  443. X  game * tmp;
  444. X  int i; 
  445. X
  446. X  tmp = (game *) malloc (sizeof(game));
  447. X  ALLOCP(tmp);
  448. X  for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  449. X    ((int *) tmp)[i] = 0;
  450. X  return(tmp);
  451. X}
  452. X
  453. X#ifdef __STDC__
  454. Xgame * copy_board(game *from, game *to)
  455. X#else
  456. Xgame * copy_board(from, to)
  457. X     game * from;
  458. X     game * to;
  459. X#endif
  460. X{
  461. X  int i; 
  462. X
  463. X  for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  464. X    ((int *) to)[i] =  ((int *) from)[i] ;
  465. X  return(to);
  466. X}
  467. X
  468. X#ifdef __STDC__
  469. Xvoid init_board(game *tgm)
  470. X#else
  471. Xvoid init_board(tgm)
  472. X  game * tgm;
  473. X#endif
  474. X{
  475. X  register int i,j;
  476. X
  477. X  clear_board(tgm);
  478. X
  479. X  for (i=1; i< 9 ; i=i+7) {
  480. X    tgm->board[i][1]= tgm->board[i][8] = ROOK ;
  481. X    tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
  482. X    tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
  483. X    tgm->board[i][4]= QUEEN;
  484. X    tgm->board[i][5]= KING;
  485. X  }
  486. X  for (i=2; i< 8 ; i=i+5) 
  487. X    for (j=1; j <=8 ; j++)
  488. X      tgm->board[i][j] = PAWN;
  489. X
  490. X  for (i=1; i <=2; i++)
  491. X    for (j=1; j <=8 ; j++) {
  492. X      tgm->color[i][j] = WHITE;
  493. X      tgm->color[i+6][j] = BLACK ;
  494. X    }
  495. X}
  496. X
  497. X#ifdef __STDC__
  498. Xdepl * new_move(void)
  499. X#else
  500. Xdepl * new_move()
  501. X#endif
  502. X{
  503. X  depl * tmp;
  504. X  int i; 
  505. X  static int counter = 0;
  506. X
  507. X  tmp = (depl *) malloc (sizeof(depl));
  508. X  ALLOCP(tmp);
  509. X  for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  510. X    ((int *) tmp)[i] = 0;
  511. X  tmp->uid = ++counter;
  512. X  tmp->whiteturn = FALSE;
  513. X  tmp->move = 0;
  514. X  return(tmp);
  515. X}
  516. X
  517. X
  518. X#ifdef __STDC__
  519. Xvoid init_move(depl *m)
  520. X#else
  521. Xvoid init_move(m)
  522. X     depl *m;
  523. X#endif
  524. X{
  525. X  m->move= 1 ;
  526. X  m->whiteturn = TRUE ;
  527. X}
  528. X
  529. X#ifdef __STDC__
  530. Xdepl * copy_move(depl *from,depl *to)
  531. X#else
  532. Xdepl * copy_move(from,to)
  533. X     depl * from;
  534. X     depl * to ;
  535. X#endif
  536. X{
  537. X  int i; 
  538. X
  539. X  for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  540. X    ((int *) to)[i] = ((int *) from)[i];
  541. X
  542. X  return(to);
  543. X}
  544. X
  545. X/* add a new move as successor to the move m */
  546. X#ifdef __STDC__
  547. Xdepl * add_trailing_move(depl *mo)
  548. X#else
  549. Xdepl * add_trailing_move(mo)
  550. X     depl * mo;
  551. X#endif
  552. X{
  553. X  mo->next = new_move();
  554. X
  555. X  mo->next->prev = mo;
  556. X  mo->next->next = (depl *) NULL;
  557. X  mo->next->sub  = (depl *) NULL;
  558. X
  559. X  mo->next->whiteturn = !( m->whiteturn ) ;
  560. X  mo->next->move = mo->move;
  561. X  if ( mo->next->whiteturn) {
  562. X    mo->next->move++;
  563. X  }
  564. X
  565. X  return(mo->next);
  566. X}
  567. X
  568. X#ifdef __STDC__
  569. Xstatic depl * add_variation(depl *mo)
  570. X#else
  571. Xstatic depl * add_variation(mo)
  572. X     depl * mo;
  573. X#endif
  574. X{
  575. X  depl *ip ; /* insertion point */
  576. X
  577. X  ip = mo ;
  578. X  while (ip->sub != (depl *) NULL )
  579. X    ip = ip->sub ;
  580. X  
  581. X  ip->sub = new_move();
  582. X
  583. X  ip->sub->prev = mo;
  584. X  ip->sub->next = (depl *) NULL;
  585. X  ip->sub->sub  = (depl *) NULL;
  586. X  
  587. X  /* as we have a fictif element heading our list, 
  588. X     ( generated by add_trailing_move() )
  589. X     we have to go back in the numbering */
  590. X  ip->sub->whiteturn =  mo->prev->whiteturn  ;
  591. X  ip->sub->move = mo->prev->move ;
  592. X
  593. X  return(ip->sub);
  594. X}
  595. X
  596. X
  597. X#ifdef __STDC__
  598. Xstatic void free_move_list(depl *d)
  599. X#else
  600. Xstatic void free_move_list(d)
  601. X     depl * d;
  602. X#endif
  603. X{  
  604. X
  605. X  if (d->next != (depl *) NULL) {
  606. X    free_move_list(d->next);
  607. X    free(d->next);
  608. X    d->next = (depl *) NULL;
  609. X  }
  610. X  if (d->sub != (depl *) NULL) {
  611. X    free_move_list(d->sub);
  612. X    free(d->sub);
  613. X    d->sub = (depl *) NULL;
  614. X  }
  615. X}
  616. X  
  617. X/* this procedure undo the effect of move m on the board g */
  618. X#ifdef __STDC__
  619. Xstatic void undo_move(game *g,depl *m)
  620. X#else
  621. Xstatic void undo_move(g,m)
  622. X     game *g;
  623. X     depl *m;
  624. X#endif
  625. X{
  626. X  int lig;
  627. X  if (m->whiteturn)
  628. X    lig = 1;
  629. X  else 
  630. X    lig = 8;
  631. X  switch (m->type) {
  632. X  case MOVE:
  633. X    clsboard(g,m->tolig,m->tocol) ;
  634. X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  635. X    break;
  636. X  case PRISE:
  637. X    setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  638. X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  639. X    break;
  640. X  case GRANDROQUE:
  641. X    clsboard(g,lig,3) ;
  642. X    clsboard(g,lig,3) ;
  643. X    setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  644. X    setboard(g,m->fromlig,5,ROOK,CURCOLOR(m)) ;
  645. X    break;
  646. X  case PETITROQUE:
  647. X    clsboard(g,lig,6) ;
  648. X    clsboard(g,lig,7) ;
  649. X    setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  650. X    setboard(g,m->fromlig,8,ROOK,CURCOLOR(m)) ;
  651. X    break;
  652. X  case EN_PASSANT:
  653. X    clsboard(g,m->tolig,m->tocol) ;
  654. X    setboard(g,m->tolig,m->fromcol,PAWN,OPPCOLOR(m)) ;
  655. X
  656. X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  657. X    break;
  658. X  case PROMOTION:
  659. X    clsboard(g,m->tolig,m->tocol);
  660. X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  661. X    break;
  662. X  case PROM_ET_PRISE:
  663. X    setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  664. X    setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  665. X    break;
  666. X  default:
  667. X    fprintf(stderr,"unable to undo move: unknown move type\n");
  668. X    break;
  669. X  }
  670. X}
  671. X
  672. X/* variation procedures == stack manipulation */
  673. X
  674. X#ifdef __STDC__
  675. Xvoid enter_variation(void)
  676. X#else
  677. Xvoid enter_variation()
  678. X#endif
  679. X{
  680. X  int l;
  681. X
  682. X  l = dr->variation ;
  683. X  
  684. X  if (l >= VARIATION_MAX) {
  685. X    error((stderr,"Maximum imbricated variation is %d",VARIATION_MAX));
  686. X  } else {
  687. X    /* save current line/variation */
  688. X    stack[l].d = m;
  689. X    stack[l].b = tos;
  690. X    stack[l].d1 = dr->iswhiteturn;
  691. X    stack[l].d2 = dr->interrupt = TRUE ;    
  692. X    /* create new */
  693. X    tos = new_board();
  694. X    (void) copy_board(stack[l].b, tos);
  695. X
  696. X    /* A variation FOLLOWS the main line 
  697. X       so we need to backtrack one move
  698. X       */
  699. X    m = add_variation(stack[l].d);
  700. X    undo_move(tos,stack[l].d);
  701. X
  702. X    /* set variables */
  703. X    l++;
  704. X    dr->variation = l;
  705. X
  706. X    output_variation(dr,VARIATION_IN);
  707. X  }
  708. X}
  709. X
  710. X#ifdef __STDC__
  711. Xvoid exit_variation(void)
  712. X#else
  713. Xvoid exit_variation()
  714. X#endif
  715. X{
  716. X  int l ;
  717. X
  718. X  l = dr->variation ;
  719. X  
  720. X  if (l == 0) {
  721. X    error((stderr,"You cannot exit from the main line (variation error?)"));
  722. X  } else {
  723. X    output_variation(dr,VARIATION_OUT);
  724. X
  725. X    l--;
  726. X    free(tos);
  727. X    free(m);
  728. X    m = stack[l].d ;
  729. X    tos = stack[l].b ;
  730. X
  731. X    dr->iswhiteturn = stack[l].d1 ;
  732. X    dr->interrupt = stack[l].d2 ;
  733. X    dr->variation = l;
  734. X  }
  735. X}
  736. X
  737. X/* ----------- semantic evaluation of move ----------- */
  738. X/* check if  position lies within the board
  739. X   */
  740. X#ifdef __STDC__
  741. Xint in_board(int l,int c)
  742. X#else
  743. Xint in_board(l,c)
  744. X     int l,c;
  745. X#endif
  746. X{
  747. X  return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
  748. X}
  749. X
  750. X/* check that the path from pos1 to pos2 is free
  751. X   */
  752. X#ifdef __STDC__
  753. Xint path_free(int l1,int c1,int l2,int c2)
  754. X#else
  755. Xint path_free(l1, c1, l2, c2)
  756. Xint l1,c1, l2, c2;
  757. X#endif
  758. X{
  759. X  int li = 1 ;
  760. X  int ci = 1 ;
  761. X  int lig, col;
  762. X
  763. X
  764. X  li = SIGN(l2-l1);
  765. X  ci = SIGN(c2-c1);
  766. X
  767. X
  768. X  if ( c1 == c2 ) {    
  769. X    col = c1;
  770. X    for (lig = l1 +li; lig != l2 ; lig +=li)
  771. X      if (tos->board[lig][col] != VOID)
  772. X    return (FALSE);
  773. X    return(TRUE);
  774. X  }
  775. X
  776. X  if ( l1 == l2) {
  777. X    lig = l1 ;
  778. X    for (col = c1 + ci; col != c2 ; col +=ci)
  779. X      if (tos->board[lig][col] != VOID)
  780. X    return (FALSE);
  781. X    return(TRUE);
  782. X  }
  783. X
  784. X  for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
  785. X    if (tos->board[lig][col] != VOID) {
  786. X      return (FALSE);
  787. X    }
  788. X  return(TRUE);
  789. X}
  790. X
  791. X/* check roque is possible */
  792. X#ifdef __STDC__
  793. Xint check_roque(void)
  794. X#else
  795. Xint check_roque()
  796. X#endif
  797. X{
  798. X  int lig, col ;
  799. X
  800. X  if (m->whiteturn)
  801. X    lig = 1 ;
  802. X  else
  803. X    lig =8;
  804. X  if (m->type == GRANDROQUE)
  805. X    for (col = 2; col < 5 ; col++)
  806. X      if (tos->board[lig][col] != VOID)
  807. X    return(FALSE);
  808. X  if (m->type == PETITROQUE)
  809. X    for (col = 6; col < 7 ; col++)
  810. X      if (tos->board[lig][col] != VOID)
  811. X    return(FALSE);
  812. X  return(TRUE);
  813. X}
  814. X  
  815. X/* check -- or guess -- where a given piece come */
  816. X#ifdef __STDC__
  817. Xint guess_piece(void) 
  818. X#else
  819. Xint guess_piece() 
  820. X#endif
  821. X{
  822. X  return(tos->board[m->fromlig][m->fromcol]); 
  823. X}
  824. X
  825. X/* try to guess the move -- low-level function */
  826. X#ifdef __STDC__
  827. Xint guess_depl(int nb, int tab[][2],
  828. X           int * pl1, int * pc1, int l2, int c2, int path)
  829. X#else
  830. Xint guess_depl(nb, tab, pl1, pc1, l2,c2,path)
  831. X     int nb;
  832. X     int tab[][2];
  833. X     int *pl1, *pc1;
  834. X     int l2,c2;
  835. X     int path;
  836. X#endif
  837. X{
  838. X  int i;
  839. X  int c,l;
  840. X
  841. X  for (i=0; i< nb; i++ ) {
  842. X    l = l2 - tab[i][0];
  843. X    c = c2 - tab[i][1];
  844. X    if (in_board(l,c))
  845. X      if ((tos->board[l][c] == m->piece) &&
  846. X      (tos->color[l][c] == CURCOLOR(m)) &&
  847. X      ( !path || (path && path_free(l,c, l2, c2))) &&
  848. X      ( ((*pl1) == 0) || ((*pl1) == l) ) &&
  849. X      ( ((*pc1) == 0) || ((*pc1) == c) ) )
  850. X      {
  851. X    *pl1 = l;
  852. X    *pc1 = c;
  853. X    return(TRUE);
  854. X      }
  855. X  }
  856. X  return(FALSE);
  857. X}
  858. X
  859. X/* check for ambiguitey in a move
  860. X   used in ouptut function: the piece had beenm already moved and
  861. X   if we guess another move, there is an ambiguity
  862. X   */
  863. X#ifdef __STDC__
  864. Xint ambiguity(int frompiece, int l2, int c2)
  865. X#else
  866. Xint ambiguity(frompiece, l2, c2)
  867. X     int frompiece, l2, c2 ;
  868. X#endif
  869. X{
  870. X  int l1 = 0 ;
  871. X  int c1 = 0 ;
  872. X
  873. X  switch(frompiece) {
  874. X  case PAWN:
  875. X    if (m->type == PRISE) {
  876. X      if (m->whiteturn)
  877. X    return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
  878. X      else
  879. X    return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
  880. X   } else {
  881. X      if (m->whiteturn)
  882. X    return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, 
  883. X              &l1,&c1, l2,c2, FALSE));
  884. X      else
  885. X    return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, 
  886. X              &l1,&c1, l2,c2, FALSE));
  887. X    }
  888. X    /* break; */
  889. X  case KNIGHT:
  890. X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  891. X    /* break; */
  892. X  case BISHOP:
  893. X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  894. X    /* break; */
  895. X  case ROOK:
  896. X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  897. X    /* break; */
  898. X  case QUEEN:
  899. X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  900. X    /* break; */
  901. X  case KING:
  902. X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  903. X    /* break; */
  904. X  default:
  905. X    break;
  906. X  }
  907. X  return(TRUE);
  908. X}
  909. X
  910. X#ifdef __STDC__
  911. Xint check_move(depl *m)
  912. X#else
  913. Xint check_move(m)
  914. X     depl * m;
  915. X#endif
  916. X{
  917. X  int l1,c1,l2,c2;
  918. X  int tmp; /* tmp boolean */
  919. X  l1 = m->fromlig;
  920. X  c1 = m->fromcol;
  921. X  l2 = m->tolig;
  922. X  c2 = m->tocol;
  923. X
  924. X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  925. X    return(check_roque());
  926. X
  927. X  if ((tos->board[l1][c1] != m->piece)||
  928. X      (tos->color[l1][c1] != CURCOLOR(m))){
  929. X    fprintf(stderr,"hum... piece should be %d \n",tos->board[l1][c1]);
  930. X    error ((stderr,": from position and piece not coherent at move (%d,%d)\n",
  931. X        m->move,m->whiteturn));
  932. X    return(FALSE);
  933. X  }
  934. X
  935. X  /* if prise === FALSE, we must not take a piece */
  936. X  if (tos->board[l2][c2] != VOID 
  937. X      && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
  938. X    (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
  939. X    return(FALSE);
  940. X  }
  941. X
  942. X  /* prendre une de ses propres pieces */
  943. X  if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
  944. X    (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
  945. X           m->move);
  946. X    return(FALSE);
  947. X  }
  948. X
  949. X  /* we check if the move is a possible one for the piece
  950. X     */
  951. X
  952. X  switch(m->piece) {
  953. X  case PAWN:
  954. X    if (m->prise) {
  955. X      if (m->whiteturn)
  956. X    tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  957. X      else
  958. X    tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  959. X   } else {
  960. X      if (m->whiteturn)
  961. X    tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
  962. X      else
  963. X    tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
  964. X    }
  965. X    /* is it a "prise en passant " */
  966. X    if ((c1 != c2) && (tos->board[l2][c2] == VOID)
  967. X    && (tos->board[l1][c2] == PAWN)) {
  968. X      m->type = EN_PASSANT ;
  969. X      /* we must perform here the "en passant" test */
  970. X      tos->board[l1][c2] = VOID ;
  971. X      tos->color[l1][c2] = VOID ;
  972. X      tmp = TRUE;
  973. X    }
  974. X    return(tmp);
  975. X    /* break; */
  976. X  case KNIGHT:
  977. X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  978. X    /* break; */
  979. X  case BISHOP:
  980. X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  981. X    /* break; */
  982. X  case ROOK:
  983. X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  984. X    /* break; */
  985. X  case QUEEN:
  986. X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  987. X    /* break; */
  988. X  case KING:
  989. X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  990. X    /* break; */
  991. X  default:
  992. X    break;
  993. X  }
  994. X
  995. X  return(TRUE);
  996. X}
  997. X
  998. X/* try to guess the move -- used for shortened notation
  999. X   */
  1000. X#ifdef __STDC__
  1001. Xint guess_move(void)
  1002. X#else
  1003. Xint guess_move()
  1004. X#endif
  1005. X{
  1006. X  int l1,c1,l2,c2;
  1007. X
  1008. X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  1009. X    return(TRUE);
  1010. X
  1011. X  l1 = m->fromlig ;
  1012. X  c1 = m->fromcol ;
  1013. X  l2 = m->tolig;
  1014. X  c2 = m->tocol;
  1015. X
  1016. X  switch(m->piece) {
  1017. X  case PAWN:
  1018. X    if (m->prise) {
  1019. X      if (m->whiteturn)
  1020. X    (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  1021. X      else
  1022. X    (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  1023. X    } else {
  1024. X      if (m->whiteturn)
  1025. X    (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
  1026. X      else
  1027. X    (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
  1028. X    }
  1029. X    break;
  1030. X  case KNIGHT:
  1031. X    (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  1032. X    break;
  1033. X  case BISHOP:
  1034. X    (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  1035. X    break;
  1036. X  case ROOK:
  1037. X    (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
  1038. X    break;
  1039. X  case QUEEN:
  1040. X    (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
  1041. X    break;
  1042. X  case KING:
  1043. X    (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
  1044. X    break;
  1045. X  default:
  1046. X    break;
  1047. X  }
  1048. X
  1049. X  if ((l1 == 0) || (c1 == 0)) {
  1050. X    if (m->whiteturn)
  1051. X      error((stderr,"unable to guess move %d white, with piece %d\n",
  1052. X         m->move,m->piece));
  1053. X    else
  1054. X      error((stderr,"unable to guess move %d black, with piece %d\n",
  1055. X         m->move,m->piece));
  1056. X    return(FALSE);
  1057. X  } else {
  1058. X    m->fromcol = c1;
  1059. X    m->fromlig = l1;
  1060. X    return(TRUE);
  1061. X  }
  1062. X}
  1063. X
  1064. X/* --------------- execution of move ----------------- */
  1065. X
  1066. X/* clear a position */
  1067. X#ifdef __STDC__
  1068. Xint clear_pos(int lig, int col)
  1069. X#else
  1070. Xint clear_pos(lig,col)
  1071. X     int lig;
  1072. X     int col;
  1073. X#endif
  1074. X{
  1075. X  tos->board[lig][col] = VOID ;
  1076. X  tos->color[lig][col] = VOID ;
  1077. X  return(TRUE);
  1078. X}
  1079. X
  1080. X/* configure the board */
  1081. X#ifdef __STDC__
  1082. Xint configure(void)
  1083. X#else
  1084. Xint configure()
  1085. X#endif
  1086. X{
  1087. X  if (configuring) {
  1088. X    if (m->piece == VOID)
  1089. X      m->piece = PAWN ;
  1090. X    tos->board[m->tolig][m->tocol] = m->piece ;
  1091. X    tos->color[m->tolig][m->tocol] = configside ;
  1092. X  }
  1093. X  return(TRUE);
  1094. X}
  1095. X
  1096. X/* execute a move, no checking */
  1097. X#ifdef __STDC__
  1098. Xint execute_move(void)
  1099. X#else
  1100. Xint execute_move()
  1101. X#endif
  1102. X{
  1103. X  register int i;
  1104. X
  1105. X  if (m->piece == VOID )
  1106. X    m->piece = PAWN;
  1107. X
  1108. X  if ((m->fromlig == 0) || (m->fromcol == 0))
  1109. X    (void) guess_move();
  1110. X  
  1111. X  /* supply to the -- maybe -- deficiency of input notation
  1112. X     */
  1113. X  if ((m->fromlig !=0) || (m->fromcol != 0))
  1114. X    m->piece = tos->board[m->fromlig][m->fromcol];
  1115. X
  1116. X  if (tos->board[m->tolig][m->tocol] != VOID) {
  1117. X    m->type = PRISE;
  1118. X    m->prise = tos->board[m->tolig][m->tocol] ;
  1119. X  }
  1120. X
  1121. X  if (!check_move(m)) {
  1122. X    if (m->whiteturn)
  1123. X      error((stderr,"white move %d illegal\n",m->move));
  1124. X    else
  1125. X      error((stderr,"black move %d illegal\n",m->move));
  1126. X  }
  1127. X
  1128. X  if (m->type == PETITROQUE) {
  1129. X    if (m->whiteturn)
  1130. X      curlig = 1 ;
  1131. X    else
  1132. X      curlig = 8 ;
  1133. X    tos->board[curlig][7] = KING;
  1134. X    tos->board[curlig][6] = ROOK;
  1135. X    tos->color[curlig][7] = tos->color[curlig][5] ;
  1136. X    tos->color[curlig][6] = tos->color[curlig][5] ;
  1137. X    (void) clear_pos(curlig, 5);
  1138. X    (void) clear_pos(curlig, 8);
  1139. X  }
  1140. X  if (m->type == GRANDROQUE) {
  1141. X    if (m->whiteturn)
  1142. X      curlig = 1 ;
  1143. X    else
  1144. X      curlig = 8 ;
  1145. X    tos->board[curlig][3] = KING;
  1146. X    tos->board[curlig][4] = ROOK;
  1147. X    tos->color[curlig][3] = tos->color[curlig][5] ;
  1148. X    tos->color[curlig][4] = tos->color[curlig][5] ;
  1149. X    (void) clear_pos(curlig, 5);
  1150. X    (void) clear_pos(curlig, 1);
  1151. X  }
  1152. X
  1153. X        
  1154. X  if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
  1155. X    if (m->piece == VOID)
  1156. X      m->piece = tos->board[m->fromlig][m->fromcol];
  1157. X    /*if (m->topiece == VOID)
  1158. X      m->topiece = tos->board[m->fromlig][m->fromcol];*/
  1159. X    tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
  1160. X    tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
  1161. X    (void) clear_pos(m->fromlig,m->fromcol);
  1162. X  }
  1163. X  
  1164. X  if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
  1165. X    tos->board[m->tolig][m->tocol] = m->promotion ;
  1166. X     
  1167. X  output_move(dr,m);
  1168. X
  1169. X  if (error_flag) {
  1170. X    (void) fprintf(dr->outfile, "\nlast position encountered:\n");
  1171. X    output_board(dr,tos);
  1172. X    close_files();
  1173. X    exit(0);
  1174. X  }
  1175. X
  1176. X  /* do we need to display the move ? */
  1177. X  if (nb_move_to_dsp > 0) {
  1178. X    for (i=0; i < nb_move_to_dsp; i++)
  1179. X      if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
  1180. X    output_board(dr,tos);
  1181. X    if (stop_at_display) {
  1182. X      output_end(dr);
  1183. X      close_files();
  1184. X      exit(0);
  1185. X    }
  1186. X      }
  1187. X  }
  1188. X
  1189. X  return(TRUE);
  1190. X}
  1191. X
  1192. X/* ------------------ automata ----------------------- */
  1193. X
  1194. X/* categorise the input for the automata */
  1195. X#ifdef __STDC__
  1196. Xint typechar(char c)
  1197. X#else
  1198. Xint typechar(c)
  1199. X     char c;
  1200. X#endif
  1201. X{
  1202. X  if (ispiece(c))
  1203. X    return(0);
  1204. X  if ((c >=  'a') && ( c <= 'h'))
  1205. X    return(1);
  1206. X  if ((c >=  '1') && ( c <= '8'))
  1207. X    return(2);
  1208. X  if ( c== '-' )
  1209. X    return(3);
  1210. X  if ((c == 'x') || (c == 'X' ))
  1211. X    return(4);
  1212. X  if (c == '=' )
  1213. X    return(5);
  1214. X  if (c == '\0' )
  1215. X    return(6);
  1216. X  return(7);
  1217. X}
  1218. X
  1219. X
  1220. X/* execute the actions decided by the automata */
  1221. X#ifdef __STDC__
  1222. Xint execute(int num,char c)
  1223. X#else
  1224. Xint execute(num,c)
  1225. X     int num;
  1226. X     char c;
  1227. X#endif
  1228. X{
  1229. X  switch (num) {
  1230. X  case 1: /* set cur piece */
  1231. X    curpiece = piece(c);
  1232. X    break;
  1233. X  case 2: /* set cur col */
  1234. X    curcol = lettertocol(c);
  1235. X    break;
  1236. X  case 3: /* set cur lig */
  1237. X    curlig = lettertolig(c);
  1238. X    break;
  1239. X  case 4: /* from = cur ; prise = false */
  1240. X    m->piece = curpiece ;
  1241. X    m->fromcol = curcol ;
  1242. X    m->fromlig = curlig;
  1243. X    /*m->topiece = curpiece;*/
  1244. X    break;
  1245. X  case 5: /* from = cur ; prise = true */
  1246. X    m->piece = curpiece ;
  1247. X    m->fromcol = curcol ;
  1248. X    m->fromlig = curlig;
  1249. X    m->type = PRISE ;
  1250. X    m->prise = curpiece;
  1251. X    break;
  1252. X  case 6: /* to = cur ; guess from */
  1253. X  case 7: /* to = cur ; guess from ; parse remaining token */
  1254. X    m->piece = curpiece ;
  1255. X    m->tocol = curcol;
  1256. X    m->tolig = curlig ;
  1257. X
  1258. X    /*m->topiece = curpiece ; /* ? */
  1259. X
  1260. X    if (configuring)
  1261. X      (void) configure();
  1262. X    else {
  1263. X      (void) execute_move();
  1264. X    }
  1265. X    break;
  1266. X  case 8: /* to = cur */
  1267. X  case 9: /* to = cur */
  1268. X    m->tocol = curcol;
  1269. X    m->tolig = curlig ;
  1270. X
  1271. X    if (configuring)
  1272. X      (void) configure();
  1273. X    else {
  1274. X      (void) execute_move();
  1275. X    }
  1276. X    break;
  1277. X  case 10: /* piece = cur piece ; prise = true */
  1278. X    /* later : guess from position */
  1279. X    m->piece = curpiece ;
  1280. X    m->type = PRISE ;
  1281. X    break;
  1282. X  case 11: /* grand roque */
  1283. X  case 12: /* petit roque */
  1284. X    (void) execute_move();
  1285. X    break;
  1286. X  case 13: /* case of simpliest algebraic notation ;
  1287. X          only e2e4 : this is the transition from e2 to e4
  1288. X          also the case of move such as Nge2
  1289. X          from =cur; prise = FALSE;
  1290. X          also:
  1291. X          curcol = ...
  1292. X          */
  1293. X    m->piece = curpiece ;
  1294. X    m->fromcol = curcol ;
  1295. X    m->fromlig = curlig;
  1296. X
  1297. X    m->type = MOVE;
  1298. X    curcol = lettertocol(c);
  1299. X  case 14: /* promotion, the "=" */
  1300. X    break;
  1301. X  case 15: /* promotion, the piece name */
  1302. X    /* to = cur ; guess from */
  1303. X  case 16: 
  1304. X    /* to = cur */
  1305. X
  1306. X    m->tocol = curcol;
  1307. X    m->tolig = curlig ;
  1308. X    /*m->topiece = curpiece ;*/
  1309. X
  1310. X    if (m->type == PRISE )
  1311. X      m->type = PROM_ET_PRISE ;
  1312. X    else
  1313. X      m->type = PROMOTION ;
  1314. X    m->promotion = curpiece = piece(c) ;
  1315. X
  1316. X    break;
  1317. X  case 17: /* execute move for promotion */
  1318. X    (void) execute_move();
  1319. X    break;
  1320. X  case -1:
  1321. X    break;
  1322. X  default:
  1323. X    break;
  1324. X  }
  1325. X  return(TRUE);
  1326. X}
  1327. X
  1328. X#ifdef __STDC__
  1329. Xint parse_number(char *token)
  1330. X#else
  1331. Xint parse_number(token)
  1332. X     char *token;
  1333. X#endif
  1334. X{
  1335. X  int curmove = 0 ;
  1336. X  int i;
  1337. X
  1338. X  /* check coherency with internal numbering */
  1339. X  i = 0;
  1340. X  while (isdigit(token[i])) {
  1341. X   curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
  1342. X  }
  1343. X  movecount = curmove ;
  1344. X  return(TRUE);
  1345. X}
  1346. X
  1347. X#ifdef __STDC__
  1348. Xint parse_text(char *text)
  1349. X#else
  1350. Xint parse_text(text)
  1351. X     char *text;
  1352. X#endif
  1353. X{
  1354. X  output_text(dr,T_TEXT, text, 0);
  1355. X  return(TRUE);
  1356. X}
  1357. X
  1358. X#ifdef __STDC__
  1359. Xint parse_comment(char *com)
  1360. X#else
  1361. Xint parse_comment(com)
  1362. X     char *com;
  1363. X#endif
  1364. X{
  1365. X  int t;
  1366. X
  1367. X  if (com[0] == '$')
  1368. X    /* we look in the long ascii table */
  1369. X    t = find_keyword(com_long, NUM_COM_CODE, NUM_COM_CODE, com, TRUE);
  1370. X  else {
  1371. X    /* we look for the comment in the short ascii table */
  1372. X    t = find_keyword(com_short, NUM_COM_CODE, NUM_COM_CODE, com,FALSE);
  1373. X    if (t == NUM_COM_CODE)
  1374. X      fprintf (stderr,"\nWhat is \"%s\" ?\n",com);   
  1375. X  }
  1376. X  if (t != NUM_COM_CODE)
  1377. X    output_text(dr,T_COMMENT, com, t);
  1378. X  return(TRUE);
  1379. X}
  1380. X
  1381. X#ifdef __STDC__
  1382. Xint parse_keyword(char *token, char *text)
  1383. X#else
  1384. Xint parse_keyword(token,text)
  1385. X     char *token;
  1386. X     char *text;
  1387. X#endif
  1388. X{
  1389. X  char c;
  1390. X
  1391. X  switch (find_keyword(keywords, NBKEYWORD, KNULL, token, TRUE)) {
  1392. X  case START:
  1393. X    /* don't forget we are configuring the previous move */
  1394. X    /* -> move 0, black */
  1395. X    configuring = FALSE;
  1396. X    m->move = 0;
  1397. X    m->whiteturn = FALSE;
  1398. X    break;
  1399. X  case CLEAR:
  1400. X    clear_board(tos);
  1401. X    m= theplay->chain;
  1402. X    free_move_list(m);
  1403. X    break;
  1404. X  case SHOWBOARD:
  1405. X    output_board(dr,tos);
  1406. X    break;
  1407. X  case TOWHITE:
  1408. X    /* don't forget we are configuring the previous move */
  1409. X    /* reset to 0,black --> 1,white */
  1410. X    m->move = 0;
  1411. X    m->whiteturn = FALSE;
  1412. X    break;
  1413. X  case TOBLACK:
  1414. X    /* reset to 1,white -> 1 black */
  1415. X    m->move = 1;
  1416. X    m->whiteturn = TRUE;
  1417. X    break;
  1418. X  case CONFIGWH:
  1419. X    configuring = TRUE ;
  1420. X    configside = WHITE;
  1421. X    m= theplay->chain;
  1422. X    free_move_list(m);
  1423. X    break;
  1424. X  case CONFIGBL:
  1425. X    configuring = TRUE ;
  1426. X    configside = BLACK;
  1427. X    m= theplay->chain;
  1428. X    free_move_list(m);
  1429. X    break;
  1430. X  case DEFAULTP:
  1431. X    init_board(tos);
  1432. X    m= theplay->chain;
  1433. X    free_move_list(m);
  1434. X    break;
  1435. X  case TITLE:
  1436. X    output_text(dr, T_TITLE, text, NULL);
  1437. X    break;
  1438. X  case SUBTITLE:
  1439. X    output_text(dr, T_SUBTITLE, text, NULL);
  1440. X    break;
  1441. X  case SCORE:
  1442. X    output_text(dr, T_SCORE, text, NULL);
  1443. X    break;
  1444. X  case LANGUE:
  1445. X    in_language = find_keyword (t_language, NBLANGUAGES, in_language,
  1446. X                   text,TRUE);
  1447. X    associe_traduction( &in_table, in_language);           
  1448. X    break;
  1449. X  case SPECIAL: /* all input, up to \n is copied to output */
  1450. X    while ((( c = getc(infile)) != EOF) && (c != '\n'))
  1451. X      (void) putc (c,dr->outfile);
  1452. X    putc ('\n', dr->outfile);
  1453. X    break;
  1454. X  case KNULL:
  1455. X  default:
  1456. X    fprintf(stderr,"unknown keyword %s\n",token);
  1457. X    break;
  1458. X  }
  1459. X  return(TRUE);
  1460. X}
  1461. X
  1462. X#ifdef __STDC__
  1463. Xint parse_roque(char *token)
  1464. X#else
  1465. Xint parse_roque(token)
  1466. X     char * token;
  1467. X#endif
  1468. X{ 
  1469. X  int i;
  1470. X
  1471. X  for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
  1472. X  if ( i < NBROQUE ) {
  1473. X    
  1474. X    m = add_trailing_move(m);
  1475. X    init_parse(m);
  1476. X
  1477. X    if (strlen(token) == 3) {
  1478. X      m->type = PETITROQUE ;
  1479. X      (void) execute(12,DUMMYCHAR);
  1480. X    } else {
  1481. X      m->type = GRANDROQUE ;
  1482. X      (void) execute(11,DUMMYCHAR);
  1483. X    }
  1484. X    /*(void) fprintf(stderr,"ROQUE\n");*/
  1485. X    return(TRUE);
  1486. X  }
  1487. X
  1488. X  return(FALSE);
  1489. X}
  1490. X
  1491. X#ifdef __STDC__
  1492. Xint  parse_move(char *token)
  1493. X#else
  1494. Xint  parse_move(token)
  1495. X     char *token;
  1496. X#endif
  1497. X{
  1498. X  register int i;
  1499. X  int correcte = FALSE ;
  1500. X  int erreursyntaxe = FALSE ;
  1501. X  int etat =0;
  1502. X  int code;
  1503. X  
  1504. X  m = add_trailing_move(m);
  1505. X  init_parse(m);
  1506. X  m->type = MOVE;
  1507. X
  1508. X  i=0;
  1509. X  while ( !correcte && !erreursyntaxe ) {
  1510. X    code = typechar(token[i]);
  1511. X    (void) execute(action[etat][code],token[i]);
  1512. X    etat = transit[etat][code] ;
  1513. X    if (etat == -1) 
  1514. X      erreursyntaxe = TRUE;
  1515. X    if (etat == FINAL)
  1516. X      correcte = TRUE ;
  1517. X    i++;
  1518. X  }
  1519. X  if (erreursyntaxe) {
  1520. X    (void) fprintf(stderr, "no comprende, senor: %s\n",token);
  1521. X    return(FALSE);
  1522. X  }
  1523. X  if (correcte) {
  1524. X    /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
  1525. X  }
  1526. X  /*init_parse(m);*/
  1527. X  return(TRUE);
  1528. X}
  1529. X
  1530. X#ifdef __STDC__
  1531. Xvoid init_parse(depl *m)
  1532. X#else
  1533. Xvoid init_parse(m)
  1534. X     depl * m ;
  1535. X#endif
  1536. X{
  1537. X
  1538. X  /* global position and piece variable initialised to 0
  1539. X     */
  1540. X  /* move and whiteturn unchanged */ 
  1541. X
  1542. X  m->type = MOVE ;
  1543. X
  1544. X  curpiece = m->piece = VOID ;
  1545. X  curcol = m->tocol = m->fromcol = 0;
  1546. X  curlig = m->tolig = m->fromlig = 0;
  1547. X
  1548. X  m->promotion = VOID;
  1549. X  m->prise = VOID;
  1550. X  m->is_check = FALSE ;
  1551. X
  1552. X  curdigit = curmove = 0;
  1553. X
  1554. X  /*if (movecount != m->move)
  1555. X    (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
  1556. X           m->move, movecount);*/
  1557. X
  1558. X}
  1559. X
  1560. X/* ------------------- top routines -------------------- */
  1561. X
  1562. X/* cette fonction analyse les arguments de la ligne de commande
  1563. X   */
  1564. X#ifdef __STDC__
  1565. Xint parse_options(int argc,char *argv[])
  1566. X#else
  1567. Xint parse_options(argc,argv)
  1568. X     int argc;
  1569. X     char * argv[];
  1570. X#endif
  1571. X{
  1572. X  int narg =1 ;
  1573. X  int i;
  1574. X  register int c;
  1575. X  char cp[132];
  1576. X  char chaine[MAXTOKLEN];
  1577. X
  1578. X  infile = stdin;
  1579. X  dr->outfile = stdout;
  1580. X  nb_move_to_dsp = 0;
  1581. X
  1582. X  while (narg < argc ) {
  1583. X    (void) strcpy (cp,argv[narg]);
  1584. X    switch (cp[0]) {
  1585. X    case '-' :
  1586. X      switch (cp[1]) {
  1587. X      case 'f' : /* from langage */
  1588. X    if  ((narg+1) >= argc )
  1589. X      fatal((stderr,"missing argument to %s option",cp));
  1590. X    narg++ ;
  1591. X    in_language = find_keyword (t_language, NBLANGUAGES,
  1592. X                    DEFAULT_INPUT_LANGUAGE,
  1593. X                    argv[narg],TRUE);
  1594. X    break;
  1595. X      case 't' : /* to langage */
  1596. X    if  ((narg+1) >= argc )
  1597. X      fatal((stderr,"missing argument to %s option",cp));
  1598. X    narg++ ;
  1599. X    out_language = find_keyword (t_language, NBLANGUAGES,
  1600. X                     DEFAULT_OUTPUT_LANGUAGE,
  1601. X                     argv[narg],TRUE);
  1602. X    break;
  1603. X      case 'o' : /* next arg is output file */
  1604. X    narg++ ;
  1605. X    if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
  1606. X      (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
  1607. X      (void) fprintf (stderr,"assume stdout for output\n");
  1608. X    }
  1609. X    break;
  1610. X      case 'e':
  1611. X    if  ((narg+1) >= argc )
  1612. X      fatal((stderr,"missing argument to %s option",cp));
  1613. X    narg++ ;
  1614. X
  1615. X    i=0;
  1616. X    nb_move_to_dsp = 0;
  1617. X    move_to_display[nb_move_to_dsp] = 0;
  1618. X    while (isdigit(argv[narg][i])) {
  1619. X      move_to_display[nb_move_to_dsp] =
  1620. X        ((int) argv[narg][i] - (int) '0')
  1621. X          + move_to_display[nb_move_to_dsp] * 10;
  1622. X      i++;
  1623. X    }
  1624. X    nb_move_to_dsp++;
  1625. X    stop_at_display = TRUE;
  1626. X    break;
  1627. X      case 'c':
  1628. X    if  ((narg+1) >= argc )
  1629. X      fatal((stderr,"missing argument to %s option",cp));
  1630. X    narg++ ;
  1631. X
  1632. X    i=0;
  1633. X    while (isdigit(argv[narg][i])) {
  1634. X      move_to_display[nb_move_to_dsp] = 0;
  1635. X      while (isdigit(argv[narg][i])) {
  1636. X        move_to_display[nb_move_to_dsp] =
  1637. X          ((int) argv[narg][i] - (int) '0')
  1638. X          + move_to_display[nb_move_to_dsp] * 10;
  1639. X        i++;
  1640. X      }
  1641. X      nb_move_to_dsp++;
  1642. X
  1643. X      if (nb_move_to_dsp > NB_MOVE_TO_DISP)
  1644. X        fatal((stderr,"max. number of move to display exceeded"));
  1645. X
  1646. X      /* process next number */
  1647. X      if (argv[narg][i] == ',')
  1648. X        i++;
  1649. X    }
  1650. X    break;
  1651. X      case 'a': /* algebraic output */
  1652. X    dr->output_move_format = ALGEBRAIC;
  1653. X    break;
  1654. X      case 's':  /* shortened output */
  1655. X    dr->output_move_format = SHORTENED;
  1656. X    break;
  1657. X      case 'b': /* display only the board, no move */
  1658. X    dr->only_board = TRUE;
  1659. X    break;
  1660. X      case 'd': /* output driver */
  1661. X    if  ((narg+1) >= argc )
  1662. X      fatal((stderr,"missing argument to %s option",cp));
  1663. X    narg++ ;
  1664. X    driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
  1665. X                  argv[narg],TRUE);
  1666. X    break;
  1667. X      case 'i': /* no headers */
  1668. X    dr->print_headers = FALSE;
  1669. X    break;
  1670. X      case 'v': /* print version */
  1671. X    /* this already done, so exit() */
  1672. X    exit(0);
  1673. X    break;
  1674. X      case 'h': /* help file */
  1675. X    (void) strcpy(chaine,LIB_DIR);
  1676. X        if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
  1677. X          fatal((stderr,"Can't find help file.\n"));
  1678. X        else {
  1679. X          while ((c = getc(fhelp)) != EOF)
  1680. X            (void) fputc(c,stderr);
  1681. X          (void) fclose(fhelp);
  1682. X      exit(0);
  1683. X        }
  1684. X         break;
  1685. X      default:
  1686. X    error((stderr,"unknown command line options %s\n",cp));
  1687. X    break;
  1688. X      }
  1689. X      break;
  1690. X    default: /* assume this is the input file */
  1691. X      if ((infile = fopen (cp,"r")) == NULL)
  1692. X    fatal((stderr,"can't open %s input file\n",cp));
  1693. X    }
  1694. X    narg++;
  1695. X  } /* process next arg */
  1696. X  return(argc);
  1697. X}
  1698. X
  1699. X#ifdef __STDC__
  1700. Xvoid close_files(void)
  1701. X#else
  1702. Xvoid close_files()
  1703. X#endif
  1704. X{
  1705. X  if (!((infile == stdin)||(infile == NULL)))
  1706. X    (void) fclose(infile);
  1707. X  if (dr->outfile != stdout )
  1708. X    (void) fclose(dr->outfile);
  1709. X}
  1710. X
  1711. X#ifdef __STDC__
  1712. Xint associe_traduction (char **table, int language)
  1713. X#else
  1714. Xint associe_traduction (table, language)
  1715. Xchar ** table;
  1716. Xint language ;
  1717. X#endif
  1718. X{
  1719. X  if (language < 0 || (language >= NBLANGUAGES))
  1720. X    error((stderr,"unknown language\n"));
  1721. X  else
  1722. X    *table = c_language[language];
  1723. X  return(language);
  1724. X}
  1725. X
  1726. X#ifdef __STDC__
  1727. Xstatic void print_all_play(play *p)
  1728. X#else
  1729. Xstatic void print_all_play(p)
  1730. Xplay *p;
  1731. X#endif
  1732. X{ 
  1733. X  depl *d;
  1734. X  d = p->chain;
  1735. X  while (d->next != NULL){
  1736. X    d = d->next;
  1737. X    output_move(dr,d);
  1738. X  }
  1739. X}
  1740. X
  1741. X/* ------------- main --------------------- */
  1742. X
  1743. X#ifdef __STDC__
  1744. Xvoid main(int argc,char *argv[])
  1745. X#else
  1746. Xint main(argc,argv)
  1747. X     int argc;
  1748. X     char * argv[];
  1749. X#endif
  1750. X{
  1751. X  (void) fprintf(stderr,"%s\n",version_string);
  1752. X  
  1753. X  /* allocation of driver descriptor */
  1754. X  dr = new_driver();
  1755. X
  1756. X  /* default configuration */
  1757. X  init_driver(dr,DEFAULT_DRIVER);
  1758. X  (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
  1759. X  (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
  1760. X
  1761. X  (void) parse_options(argc,argv);
  1762. X
  1763. X  (void) associe_traduction (&in_table, in_language);
  1764. X  (void) associe_traduction (&(dr->out_table), out_language);
  1765. X
  1766. X  /* assoc driver */
  1767. X  init_driver(dr,driver);
  1768. X
  1769. X  configuring = FALSE;
  1770. X  configside = VOID;
  1771. X
  1772. X  /* initialise output file */
  1773. X  output_init(dr);
  1774. X
  1775. X  if (error_flag)
  1776. X    fatal((stderr,"too many errors"));
  1777. X
  1778. X  /* allocation of board descriptor */
  1779. X  tos = new_board();
  1780. X  init_board(tos);
  1781. X
  1782. X  /* allocation of move descriptor */
  1783. X  m = new_move();
  1784. X  m->type = VOID ;
  1785. X  /*init_move(m);*/
  1786. X  
  1787. X  /* allocation of the play descriptor */
  1788. X  theplay = (play *) malloc (sizeof(play)) ;
  1789. X  theplay->initial = tos ;
  1790. X  theplay->chain   = m ;
  1791. X  movecount = 1;
  1792. X
  1793. X  /* main analysis routine */
  1794. X  yyin = infile ;
  1795. X  yyout = stderr ;
  1796. X
  1797. X  /*init_parse(m); */
  1798. X  yylex();
  1799. X
  1800. X  if ((count == 0) && !error_flag)
  1801. X    output_board(dr,tos);
  1802. X
  1803. X  if (error_flag) {
  1804. X    error((stderr,"last valid position:\n"));
  1805. X    output_board(dr,tos);
  1806. X    fatal((stderr,"too many errors"));
  1807. X  }
  1808. X      
  1809. X  /* terminates output files */
  1810. X  output_end(dr);
  1811. X
  1812. X  /* close files */
  1813. X  close_files();
  1814. X
  1815. X  /* exit properly */
  1816. X#ifdef __STDC__
  1817. X#else
  1818. X  exit(0);
  1819. X#endif
  1820. X}
  1821. END_OF_FILE
  1822. if test 40751 -ne `wc -c <'notation.c'`; then
  1823.     echo shar: \"'notation.c'\" unpacked with wrong size!
  1824. fi
  1825. # end of 'notation.c'
  1826. fi
  1827. echo shar: End of archive 4 \(of 4\).
  1828. cp /dev/null ark4isdone
  1829. MISSING=""
  1830. for I in 1 2 3 4 ; do
  1831.     if test ! -f ark${I}isdone ; then
  1832.     MISSING="${MISSING} ${I}"
  1833.     fi
  1834. done
  1835. if test "${MISSING}" = "" ; then
  1836.     echo You have unpacked all 4 archives.
  1837.     rm -f ark[1-9]isdone
  1838. else
  1839.     echo You still need to unpack the following archives:
  1840.     echo "        " ${MISSING}
  1841. fi
  1842. ##  End of shell archive.
  1843. exit 0
  1844.  
  1845. --
  1846. Henry Thomas - IRISA          - E-mail: Henry.Thomas@irisa.fr 
  1847. Campus Universitaire de Beaulieu - Phone: (+33)99 36 20 00 +549  
  1848. 35042 RENNES CEDEX FRANCE      - Fax: (+33)99 38 38 32 Telex: UNIRISA 950473F
  1849. Telex Atlas X400: /X121=842950473/@atlas.fr, Fax:/X121=200099383832/@atlas.fr
  1850. --
  1851.  
  1852. exit 0 # Just in case...
  1853. -- 
  1854. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1855. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1856. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1857. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1858.